/*

 *日期: 2017-2-17

 *名称: king.js

 *版本: 1.5

 *作者: henger.wang

 *免jQuery|Zepto冲突方法: append|remove|find|before|after|prev|next|eq|isFunction|isEmptyObject|slice

 *自定义方法: dialog|alert|confirm|tips|getLocalImage|viewImage|go|rdate|rtime|ftime|rem|gotop|scrollNode|scrollOffset|scrollEnd|isEmpty

 *新增：支持AMD、CMD规范

 */
;(function(global, factory){
	if (typeof define === 'function' && define.amd) {
        // AMD

        define(factory(global));
    } else if (typeof exports === 'object') {
        // CMD

        module.exports = factory(global);
    } else {
        global.$ = global.King = factory(global);
    }
})(window, function(global){
	var King = function(selector){
		return King.init(selector)
	}
	var $ = global.$ || King,
		hasJZ = $ == global.jQuery || $ == global.Zepto
		arrFn = Array.prototype;
	King.init = function(selector){
		var dom;
		if($.isFunction(selector)){
			return $(document).ready(selector);
		}else if(typeof selector == "string"){
			if(/<[^>]*?>/.test(selector)){
				dom = tool.createDom(selector)
			}else{
				dom = document.querySelectorAll(selector)
			}
		}else if(selector.length){
			dom = selector;
			selector = null
		}else if(typeof selector == "object"){
			dom = [selector];
			selector = null
		}
		return newK(dom, selector)
	}
	function newK(dom, selector){
		if(arguments.length == 0)return false;
		return new K(dom, selector)
	}
	function isK(dom){
		return dom instanceof K
	}
	function K(dom, selector){
		var i, len = dom ? dom.length : 0;
	    for (i = 0; i < len; i++) this[i] = dom[i];
	    this.length = len;
	    this.splice = function(){};
	    this.selector = selector || ''
	}
	/*

	*工具

	*有jquery的话，tool将被用作内部方法，没有jquery,则即是内部方法，也会被公开到全局$中

	*/
	var tool = {
		isFunction: function(fun){
			return typeof fun === "function"
		},
		isEmptyObject: function(obj){
			var key;
			for(key in obj)return false;
			return true
		},
		extend: function(target){
			for(var x in arguments){
				if(arguments.length == 1){
					var object = target;
					target = $;
				}else{
					if(x == 0)continue;
					var object = arguments[x];
				}
				for(var o in object){
					target[o] = object[o]
				}
			}
			return target
		},
		createDom: function(str){
			var container = document.createElement("div");
			container.innerHTML = str;
			var node = container.childNodes;
			container = null;
			return node
		},
		each: function(object, callback){
			arrFn.every.call(object, function(el, idx){
				//将each的回调环境指向到具体的节点内，this即节点

				return callback.call(el, el, idx) !== false;
			});
			return object;
		}
	}
	/*

	*静态方法

	*这里调用tool方法必须指明tool，可随意调用dom方法

	*/
	var static = {
		dialog: function(data){
			//{title:"温馨提示",text:'你好啊',btns:[{name:"确定", ev: function(){}},{name:"取消", ev:function(){}}]}

			var data = {
				title: data.title || "提示",
				text: data.text || "没有内容",
				btns: data.btns || [{"name":"确定"}],
				init: data.init
			};
			var box = $('<div class="king_box"></div>');
			box.append('<div class="king_box_in"><div class="king_box_title">'+data.title+'</div><div class="king_box_cont">'+data.text+'</div><div class="king_box_btns"></div></div>');
			var btnsWrap = box.find(".king_box_btns");
			box[0].hide = function(){
				btnsWrap.children().off()
				box.remove();
			}
			$.each(data.btns,function(){
				var _this = this;
				var btn = $('<span>'+this.name+'</span>');
				btnsWrap.append(btn[0])
				btn.on("click", function(){
					$.isFunction(_this.ev) ? _this.ev.call(box[0]) : box[0].hide();
				});
			});
			$("body").append(box);
			data.init&&data.init();
			return box
		},
		alert: function(text, callback){
			return this.dialog({text: text, btns: [{name: "确定", ev: callback}]})
		},
		confirm: function(text){
			return this.dialog({text: text, btns: [{name: "确定", ev: arguments[1]}, {name: "取消", ev: arguments[2]}]})
		},
		tips: function(text){
			var tip = $('<div class="king_pop_tips"><span>'+text+'</span></div>');
			$("body").append(tip);
			setTimeout(function(){
				tip.remove();
			},2000);
			return {hide: function(){tip.remove()}}
		},
		loader: function(str){
			var loader = $('<div class="king_ld"><div class="king_lds"><div class="king_lds_in"><span></span>'+(str||'')+'</div></div></div>');
			$("body").append(loader);
			return loader
		},
		getLocalImage: function(){console.log("getLocalImage")},
		viewImage: function(){console.log("viewImage")},
		go: function(url){
			global.location.href = url
		},
		gotop: function(){
			global.scrollTo(0, 0)
		},
		rtime: function(obj, t, callback) {
		    if(t > 0){
				$(obj).text(t--);
				setTimeout(function(){
					rTime(obj,t,callback);
				},1000);
		    }else if(typeof callback == "function"){
				callback()
			}
		},
		rdate: function(obj, t, callback){
			if(t > 0) {
				$(obj).text(timeFormat(t--));
				setTimeout(function(){
					rDate(obj,t,callback)
				},1000);
			}else if(typeof callback == "function"){
				callback()
			}
		},
		ftime: function(t){
			t = parseInt(t);
			var d = parseInt(t/(24*3600));
			var h = parseInt((t-(d*24*3600))/3600);
			h = h<10?"0"+h:h;
			var m = parseInt((t-(d*24*3600)-h*3600)/60);
			m = m<10?"0"+m:m;
			var s = parseInt(t-(d*24*3600)-h*3600-m*60);
			s = s<10?"0"+s:s;
			return (d==0?"":d+"天 ")+h+":"+m+":"+s;
		},
		rem: function(baseSize, baseWidth){
			var docEl = global.document.documentElement,
				resizeEvt = 'orientationchange' in global ? 'orientationchange' : 'resize',
				baseSize = baseSize || 20,
				baseWidth = baseWidth || 320;
			var recalc = function () {
				var clientWidth = docEl.clientWidth;
				if (clientWidth){
					var fontSize = baseSize * (clientWidth / baseWidth);
					docEl.style.fontSize =  (fontSize>40?40:fontSize)+ 'px';
				}
			};
			global.addEventListener(resizeEvt, recalc, false);
			recalc();
		},
		scrollEnd: function(callback){
			$(global).scroll(function(){
				if($(global).scrollTop()>=$(global).height()-$(global).height()){
					tool.isFunction(callback)&&callback();
				}
			});
		},
		isEmpty: function(obj){
			return obj == null || obj == undefined || obj+'' == ''
		}
	}
	/*

	*操作dom，支持链式执行

	*有jquery的话，King.dom将不会被执行，可随意调用tool方法

	*/
	var dom = {
		width: function(){
			if(this[0] === global){
				return document.documentElement.clientWidth
			}else{
				return global.getComputedStyle(this[0], null).width
			}
		},
		height: function(){
			if(this[0] === global){
				return document.documentElement.clientHeight
			}else{
				return global.getComputedStyle(this[0], null).height
			}
		},
		append: function(node){
			this.addDom(node, function(newNode){
				this.appendChild(newNode)
			});
			return this
		},
		remove: function(){
			return $.each(this, function(){
				if(this.parentNode != null){
					$(this).off();//dom将被移除，需要移除监听事件，释放内存

					this.parentNode.removeChild(this);
				}
			})
			return this
		},
		find: function(selector){
			return $(this[0].querySelectorAll(selector))
		},
		children: function(selector){
			var type, childs = this[0].childNodes;
			if(!selector)return $(childs);
			if(/^\w+$/.test(selector)){
				type = "nodeName"
			}else if(/^\.\w+$/.test(selector)){
				type = "className"
			}else if(/^#\w+$/.test(selector)){
				type = "id"
			}
			return $(arrFn.map.call(childs, function(el){
				return el[type].indexOf(selector) > 0
			}))
		},
		before: function(node){
			this.addDom(node, function(newNode){
				this.parentNode.insertBefore(newNode, this)
			});
			return this
		},
		after: function(node){
			this.addDom(node, function(newNode){
				var next = this.nextElementSibling;
				next ? this.parentNode.insertBefore(newNode, next) : this.parentNode.appendChild(newNode)			
			});
			return this
		},
		prev: function(){
			if(!$.isEmptyObject(this[0])){
				var previous = this[0].previousElementSibling;
				previous ? arrFn.splice.call(this, 0, this.length, previous) : arrFn.splice.call(this, 0, this.length)
			}
			return this
		},
		next: function(){
			if(!$.isEmptyObject(this[0])){
				var next = this[0].nextElementSibling;
				next ? arrFn.splice.call(this, 0, this.length, next) : arrFn.splice.call(this, 0, this.length);
			}
			return this
		},
		eq: function(i){
			return this.slice(i, i+1)
		},
		text: function(str){
			if(str){//填充文本
				$.each(this, function(){
					this.innerText = str
				});
				return this
			}else{//获取文本
				return this[0].firstChild.nodeValue
			}
		},
		slice: function(){
			return $(arrFn.slice.apply(this, arguments))
		},
		addDom: function(node, callback){
			if(typeof node == "string"){
				node = tool.createDom(node)[0]
			}else if(node.length == 1){
				node = node[0];
			}
			if(typeof node == "object" && !node.length){
				$.each(this, function(){
					//当前this指向遍历的元素节点，node为新节点,callback执行时，将上下文指向当前this
					callback.call(this, node)
				})
			};
			return this
		},
		on: function(type, selector, callback){
			$.each(this, function(){
				if(typeof selector == "function"){
					var handler = selector
				}else if(typeof selector == "string"){
					//remove...Listener只能移除指定名称的方法，这里要定义一个handler，而不是直接在add...listener里写fun
					var handler = function(e){
						//在代理节点下查找被代理的节点
						var childNodes = this.querySelectorAll(selector);
						//如果在被代理节点中匹配到当前元素，则执行callback并传入第一个参数e，this指向当前元素
						arrFn.indexOf.call(childNodes, e.target)> -1 && callback.call(e.target, e)
					}
				}
				this.listener ? this.listener.push({type: type, event: handler}) : this.listener = [{type: type, event: handler}];
				this.addEventListener(type, handler, false)
			});
			return this
		},
		off: function(type){
			$.each(this, function(){
				if(this.listener){
					var listener = this.listener.slice(0);
					for(var i = 0;i < listener.length;i++){
						var typel = listener[i].type;
						if(type && typel != type)continue;
						this.removeEventListener(typel, listener[i].event, false);
						this.listener.splice(0,1)
					}
					this.listener.length == 0 && (this.listener = null)
				}
			});
			return this
		},
		ready: function(callback){
			/complete|loaded|interactive/.test(document.readyState) && document.body ? callback($) :
				document.addEventListener("DOMContentLoaded", function(){callback($)}, false)
			return this
		}
	}
	if(hasJZ){
		$.extend($, static);
		tool = dom = null
	}else{
		tool.extend(King, static, tool);
		K.prototype = dom;
	}
	return $
});